home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Mac Game Programming Gurus
/
TricksOfTheMacGameProgrammingGurus.iso
/
Information
/
CSMP Digest
/
volume 1
/
csmp-v1-139.txt
< prev
next >
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
NeXTSTEP
RISC OS/Acorn
UTF-8
Wrap
Text File
|
1994-12-08
|
59.4 KB
|
1,490 lines
|
[
TEXT/R*ch
]
C.S.M.P. Digest Mon, 13 Jul 92 Volume 1 : Issue 139
Today's Topics:
Instance Variables moving in Think C - How to stop
Dynamic Runtime Method Dispatch (Was Re: Is System 7 written in C++?)
Correctly handling long tasks
Screensaver erasurE
Getting User's Color Control Panel Settings
Icons dragging
Is This Fond PostScript ?!
Warning: THINK Pascal glue for GetZoneList is dangerous!
The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
The digest is a collection of article threads from the internet newsgroup
comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi-
regularly and want an archive of the discussions. If you don't know what a
newsgroup is, you probably don't have access to it. Ask your systems
administrator(s) for details. (This means you can't post questions to the
digest.)
Each issue of the digest contains one or more sets of articles (called
threads), with each set corresponding to a 'discussion' of a particular
subject. The articles are not edited; all articles included in this digest
are in their original posted form (as received by our news server at
cs.uoregon.edu). Article threads are not added to the digest until the last
article added to the thread is at least one month old (this is to ensure that
the thread is dead before adding it to the digest). Article threads that
consist of only one message are generally not included in the digest.
The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu
[128.223.8.8] in the directory /pub/mac/csmp-digest. The most recent issues
are available from sumex-aim.stanford.edu [36.44.0.6] in the directory
/info-mac/digest/csmp. If you don't have ftp capability, the sumex archive
has a mail server; send a message with the text '$MACarch help' (no quotes)
to LISTSERV@ricevm1.rice.edu for more information.
These digest is also available via email. Just send a note saying that you
want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
automatically receive each new issue as it is created. Sorry, back issues
are not available through the mailing list.
Send administrative mail to mkelly@cs.uoregon.edu.
-------------------------------------------------------
From: caw@cs.mu.OZ.AU (Chris Wright)
Subject: Instance Variables moving in Think C - How to stop
Organization: Computer Science, University of Melbourne, Australia
Date: Sun, 7 Jun 1992 12:35:19 GMT
When defining a class in Think C, which has char array instance vars,
it seems important to remember that many of the standard ANSI calls
could compact memory.e.g.:
struct person : indirect {
char name[10];
void SetName(char *);
void PrintMessage( void );
};
void person::SetName(char* theName)
{
strcpy(name, theName);
}
void PrintMessage( void )
{
printf("My name is %s", name);
}
This doesn't always print out with the right name, 'cos I think memory
is being compacted, and as classes are addressed as handles, we are in
trouble.
Does this mean that I have to surround all ANSI type calls with HLock() and
HUnlock()?
Help would be appreciated...
chris
+++++++++++++++++++++++++++
From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy)
Organization: Kalamazoo College
Date: Sun, 7 Jun 1992 13:02:58 GMT
caw@cs.mu.OZ.AU (Chris Wright) writes:
>When defining a class in Think C...
>it seems important to remember that many of the standard ANSI calls
>could compact memory.e.g.:
>
>void person::SetName(char* theName)
>{
> strcpy(name, theName);
>}
>
>...I think memory
>is being compacted, and as classes are addressed as handles, we are in
>trouble.
>
>Does this mean that I have to surround all ANSI type calls with HLock() and
>HUnlock()?
We just finished discussing this in the tcl-talk discussion list. When
you call strcpy(), if the segment with the ANSI library isn't loaded, it
has to pull it in. That's what causes memory to move.
Either you have to (1) lock "this" every time you call a function in
another segment, or (2) make sure the function's segment won't be
purged.
(1): The best way to do this is:
{ Boolean wasLocked; wasLocked = Lock(TRUE);
// do your stuff
Lock(wasLocked); }
(2): You can stick the function in the main() segment, or the calling
segment, or you can make a dummy reference to it early in the program
and just never call UnloadSeg on it. Either way, it'll always be
available.
I prefer (1), but it requires a lot of extra typing and planning. If
you do (2), realize that you may never be able to go back to (1)--if you
code with the assumption that calls across segments won't move memory,
you'll always have to have all segments loaded. This may kick up your
app's memory requirements quite a lot.
- --
Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy
Tact is the art of making a point without making an enemy.
- Howard W. Newton
+++++++++++++++++++++++++++
From: mspace@netcom.com (Brian Hall)
Date: Sun, 07 Jun 92 23:57:26 GMT
Organization: Netcom - Online Communication Services (408 241-9760 guest)
caw@cs.mu.OZ.AU (Chris Wright) writes:
>When defining a class in Think C, which has char array instance vars,
>it seems important to remember that many of the standard ANSI calls
>could compact memory.e.g.:
>struct person : indirect {
> char name[10];
> void SetName(char *);
> void PrintMessage( void );
> };
>Does this mean that I have to surround all ANSI type calls with HLock() and
>HUnlock()?
Just the ones that may actually move memory. printf is quite likely, but
strcpy is safe. Since you get the sources, just take a look at them.
If things like strcpy and strcat are in asm, or use blockmove, you don't
need to worry - they won't move memory.
- --
\ | / | Brian Hall mspace@netcom.com
- : - | Mark/Space Softworks Applelink: markspace
/|\ | America Online: MarkSpace
|-+-| |
/-\|/-\ | People don't kill people, toasters kill people.
+++++++++++++++++++++++++++
From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy)
Date: 8 Jun 92 02:51:52 GMT
Organization: Kalamazoo College
mspace@netcom.com (Brian Hall) writes:
>caw@cs.mu.OZ.AU (Chris Wright) writes:
>
>>it seems important to remember that many of the standard ANSI calls
>>could compact memory...
>>
>>Does this mean that I have to surround all ANSI type calls with HLock() and
>>HUnlock()?
>
>Just the ones that may actually move memory. printf is quite likely, but
>strcpy is safe.
Not if it's in a different segment. Any cross-segment function call can
cause memory to be moved, unless you take steps to ensure otherwise
(namely, loading the segment in beforehand and never UnloadSeg'ing it).
This usually happens with ANSI since ThC's ANSI library is about 5K
short of the maximum segment size, so most calls to it are from a
different segment.
- --
Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy
To exit to shell in the mini-debugger, enter SM 0 A9 F4 and then G 0.
+++++++++++++++++++++++++++
From: jstevens@crick.ssctr.bcm.tmc.edu (Jason Philip Stevens)
Date: 8 Jun 1992 15:11:57 GMT
Organization: Baylor College of Medicine, Houston, Tx
In article <9215922.21843@mulga.cs.mu.OZ.AU>, caw@cs.mu.OZ.AU (Chris Wright) writes:
|> When defining a class in Think C, which has char array instance vars,
|> it seems important to remember that many of the standard ANSI calls
|> could compact memory.e.g.:
|> struct person : indirect {
|> char name[10];
|> void SetName(char *);
|> void PrintMessage( void );
|> };
|>
|> void person::SetName(char* theName)
|> {
|> strcpy(name, theName);
|> }
|>
|> void PrintMessage( void )
|> {
|> printf("My name is %s", name);
|> }
^ I assume this 'name' actually the char* passed
to SetName as 'theName' rather than the instance
variable in class person...
|> This doesn't always print out with the right name, 'cos I think memory
|> is being compacted, and as classes are addressed as handles, we are in
|> trouble.
|>
|> Does this mean that I have to surround all ANSI type calls with HLock() and
|> HUnlock()?
|>
|> Help would be appreciated...
Well, I'll take a stab at it...
if you have:
person* someGuy;
char* hisName;
someGuy = new person;
someGuy->name = "someName"; /* As an instance variable of a class, this
pointer should not be passed to any routine
that moves memory (as listed in IM6 appendix */
someGuy->SetName(hisName); /* 'hisName' is now a copy of the string, in
someGuy->name, rather than a copy of pointer.
As such, while someGuy->name may get moved,
'hisName' will not (it's not an instance
variable or a pointer to an instance
variable) */
PrintMessage(hisName); /* Perhaps this is a matter of taste, but this
really should take an argument. Is also makes
it clear exactly which version of 'name' you
mean, since in the code fragment above there
_is_ no global variable called 'name'... */
This should work (I hope).
- -jps
- --
Jason Stevens Internet: jstevens@bcm.tmc.edu
Network User Services Voice: (713) 798-7370
Baylor College of Medicine Opinions expressed are mine alone.
+++++++++++++++++++++++++++
From: larrym@mtxinu.COM (Larry Meyer - mac weenie)
Date: 9 Jun 92 18:43:44 GMT
Organization: Xinet, Berkeley
In article <4=-lzmq.mspace@netcom.com> mspace@netcom.com (Brian Hall) writes:
>caw@cs.mu.OZ.AU (Chris Wright) writes:
>
>>When defining a class in Think C, which has char array instance vars,
>>it seems important to remember that many of the standard ANSI calls
>>could compact memory.e.g.:
>>struct person : indirect {
>> (...stuff deleted...)
>>Does this mean that I have to surround all ANSI type calls with HLock() and
>>HUnlock()?
>
>Just the ones that may actually move memory. printf is quite likely, but
>strcpy is safe. Since you get the sources, just take a look at them.
>If things like strcpy and strcat are in asm, or use blockmove, you don't
>need to worry - they won't move memory.
>
I agree that one can assume that something as trivial as strcpy will
never trigger memory movement, but I'd just like to emphasize that you
have to be real careful about such assumptions. for example, I once
had a problem with using qsort() on an array stored in an unlocked
Handle. I was getting bizarre results in my callback routine, and of
course it turned out that memory was getting compacted. Obviously, one
would naively think that qsort would never use dynamic memory (one of
the features of this algo is that it operates "in place" on an array
and requires no scratch memory). I never looked into it, but I suspect
that the memory movement occurred because of some initialization
calls within qsort.
i.e. it seems safe to say that one should assume that ANY non-trivial
ANSI call may move memory (unless Symantec actually documents
which calls do move memory, a-la Apple's list).
/*************************************************************
Larry Meyer Mac/Unix Programmer @ Xinet, Berkeley CA
larrym@xinet.com
*************************************************************/
- --
/*************************************************************
Larry Meyer Mac/Unix Programmer @ Xinet, Berkeley CA
larrym@xinet.com (ask me about max<->unix stuff)
---------------------------
From: orpheus@reed.edu (P. Hawthorne)
Subject: Dynamic Runtime Method Dispatch (Was Re: Is System 7 written in C++?)
Date: 8 Jun 92 06:01:17 GMT
Organization: Reed College, Portland, Oregon
Prometheus Hawthorne exclaims:
> My kingdom for a new and improved object method dispatching technique!
Bruce Hoult asserts:
> The method dispatch code possible with C++ [....] is about as efficient as
> it's possible to get.
Kent Sandvik laments:
> And no dynamic runtime method dispatching, something that Objective-C has.
What good is inheritance without dynamic runtime method dispatch?
For special cases where it is obvious to me that only one class could be
receiving, I would be okay with prefacing the method call with a keyword.
I could even accept some special case for messages sent to self, but for
my purposes, dynamic dispatch should be the default.
I wish there was a way for me to disassemble some Objective C.... Hmmm.
If you assume that there is a class tag at the start of an instance, a
method call could consist of pushing the address of the dispatch table plus
the class tag plus the method selector... Duh.
Suppose I came up with a low instruction-count dispatching technique.
I'd have to write a compiler, or evangelize like crazy. I guess this is a
case of just doing it before doing it fast.
Back to the old source editor,
Theus (orpheus@reed.edu)
+++++++++++++++++++++++++++
From: lsr@taligent.com (Larry Rosenstein)
Date: 10 Jun 92 01:48:16 GMT
Organization: Taligent, Inc.
In article <1992Jun8.060117.28937@reed.edu>, orpheus@reed.edu (P. Hawthorne)
writes:
>
> Bruce Hoult asserts:
> > The method dispatch code possible with C++ [....] is about as efficient as
> > it's possible to get.
>
> Kent Sandvik laments:
> > And no dynamic runtime method dispatching, something that Objective-C has.
>
> What good is inheritance without dynamic runtime method dispatch?
What Kent is referring to is the ability to send any message to any object. You
can't do this in C++ because everything is type-checked at compile time. You
can do this in Lisp or Smalltalk or Objective-C where there are no types (or
they are optional). The price for this flexibility is that the message mightg
not be understood by the object, and that the dispatching is a bit slower.
C++ has virtual function calls in which the exact code that gets run is not
determined until runtime. I agree with Bruce that the C++ implementation is
about as fast you can get, at the cost of using extra memory for vtable
(compared to MPW Object Pascal, for example).
> For special cases where it is obvious to me that only one class could be
> receiving, I would be okay with prefacing the method call with a keyword.
> I could even accept some special case for messages sent to self, but for
> my purposes, dynamic dispatch should be the default.
In fact, in MPW Object Pascal this kind of optimization is made at link-time
based on how the code was written. If there is only one implementation of a
method then the call doesn't go through any dispatcher at all. This is
different from C++ where you have to make a function virtual or not. I agree
with you that virtual should have been the default in C++.
> method call could consist of pushing the address of the dispatch table plus
> the class tag plus the method selector... Duh.
Actually you need to push the receiver, so you can get the class information
from that.
In general a method dispatcher is a function that maps the class ID gotten from
the receiver and the method ID that the caller pushes to the function that you
want to call. (You can extend this to take into account class IDs from more
than one parameter.)
In C++, the method ID happens to be an index into the vtable that the compiler
computes at compile-time. Also, the mapping is done inline with the call, so
the dispatching is very fast.
In something like Objective-C, the compiler can't compute something like an
index at compile time, because you can send any message to any object. Instead
the dispatcher has to do more of a lookup at runtime. Generally, you would use
a hash table to speed this up.
(Actually, if you wanted to there's no reason why you couldn't implement more
dynamic dispatching in C++. C++ supports taking pointers to member functions,
and once you have that it's pretty easy to store these pointers in tables, look
them up, etc.)
- --
Larry Rosenstein
Taligent, Inc.
lsr@taligent.com
---------------------------
From: Adrian C Ruigrok
Subject: Correctly handling long tasks
Date: 8 Jun 92 13:41:44 GMT
Organization: Bell-Northern Research
In communications applications, like MacTCP and Appletalk apps, it is common to
be stuck waiting for another machine to respond for 15s or longer. When there
is a timeout in progress, you can be out of touch for a very long time. What
is the best way to at least let the user use his other applications?
I would have thought that you would be able to do something with asynchronous
calls something like this
MyAsyncCall()
while (not done my async called stuff) {
WaitNextEvent(...) // so others can do something at least
}
What I am not sure of is whether WaitNextEvent is the best way, and what the
parameters to WaitNextEvent would be.
I am told that there is a problem with WaitNextEvent that prevents you from
using it in this context. However, I can't think what else to do, and there
has to be a better way to do things than a synchronous call!
Thanks,
Adrian
- ---------------------------------------------------
Adrian Ruigrok
Bell-Northern Research
Ottawa, Canada
+++++++++++++++++++++++++++
From: peirce@outpost.SF-Bay.org (Michael Peirce)
Date: 9 Jun 92 01:05:12 GMT
Organization: Peirce Software
In article <1992Jun8.134144.15334@bwdls61.bnr.ca> (comp.sys.mac.programmer), Adrian C Ruigrok writes:
> In communications applications, like MacTCP and Appletalk apps, it is common to
> be stuck waiting for another machine to respond for 15s or longer. When there
> is a timeout in progress, you can be out of touch for a very long time. What
> is the best way to at least let the user use his other applications?
>
> I would have thought that you would be able to do something with asynchronous
> calls something like this
>
>
> MyAsyncCall()
> while (not done my async called stuff) {
> WaitNextEvent(...) // so others can do something at least
> }
>
>
> What I am not sure of is whether WaitNextEvent is the best way, and what the
> parameters to WaitNextEvent would be.
>
> I am told that there is a problem with WaitNextEvent that prevents you from
> using it in this context. However, I can't think what else to do, and there
> has to be a better way to do things than a synchronous call!
Here's a snippet of code I've used in the past. You call this where
you have you WaitNextEvent and makes for slightly cleaner code.
PROCEDURE YieldTime;
CONST
noEvent = 0;
VAR
event : EventRecord;
BEGIN {YieldTime}
IF WaitNextEvent(noEvent, event, 1, NIL) THEN ;
END; {YieldTime}
This approach is OK for moderately quick & dirty use, but two things
would be better:
(1) Put up a dialog if things are taking more than a short amount
of time. Let the user cancel the operations if they want.
(2) Don't get into this situation in the first place. Use a state
machine and poll for the completion of steps in the main event loop.
This lets the user get work done while waiting.
- -- Michael Peirce -- peirce@outpost.SF-Bay.org
- -- Peirce Software -- Suite 301, 719 Hibiscus Place
- -- Makers of... -- San Jose, California USA 95117
- -- -- voice: (408) 244-6554 fax: (408) 244-6882
- -- SMOOTHIE -- AppleLink: peirce & America Online: AFC Peirce
---------------------------
From: jryan@adobe.com (Jim Ryan)
Subject: Screensaver erasurE
Organization: Adobe Systems, Inc.
Date: Mon, 8 Jun 1992 18:50:44 GMT
I'm drawing a few picts, textEdit fields, and scrollbars in a modal dialog...
the problem is that when a screensaver kicks in and then out, the picts
and the TE aren't redrawn. To fix the problem, I looked
for " if (dialogEvent->what == updateEvt) {" in my dialogFilter, and recalled
the function that draws the picts, and did a TEUpdate for the text... however,
this causes the text to flicker like crazy in the dialog, as apparently
once the updateEvt is a go, ModalDialog keeps calling it. The picts
don't flicker, but if the cursor is placed over them, then the cursor flickers,
which would indicate to me that it's being redrawn repeatedly, as the text
seems to be. I thought I'd be clever and set dialogEvent->what to something
else, like nullEvent, after doing my redrawing so ModalDialog wouldn't
keep falling into my "if", but then the controls, etc., weren't redrawn, as
was the case If I returned TRUE.
Q: Is there a better way to do this, and/or what might I be doing
wrong that's causing the flicker. How do YOU redraw your modal dialogs
after a screensaver erases everything? Any hints would be most graciously
welcomed.
Thanks a bunch,
jr
place the usual and unusual disclaimers here... or there... or...
+++++++++++++++++++++++++++
From: absurd@applelink.apple.com (Tim Dierks, software saboteur)
Date: 8 Jun 92 19:58:15 GMT
Organization: MacDTS Misfits
In article <1992Jun8.185044.29228@adobe.com>, jryan@adobe.com (Jim Ryan) writes:
>
> I'm drawing a few picts, textEdit fields, and scrollbars in a modal dialog...
> the problem is that when a screensaver kicks in and then out, the picts
> and the TE aren't redrawn. To fix the problem, I looked
> for " if (dialogEvent->what == updateEvt) {" in my dialogFilter, and recalled
> the function that draws the picts, and did a TEUpdate for the text... however,
> this causes the text to flicker like crazy in the dialog, as apparently
> once the updateEvt is a go, ModalDialog keeps calling it. The picts
> don't flicker, but if the cursor is placed over them, then the cursor flickers,
> which would indicate to me that it's being redrawn repeatedly, as the text
> seems to be. I thought I'd be clever and set dialogEvent->what to something
> else, like nullEvent, after doing my redrawing so ModalDialog wouldn't
> keep falling into my "if", but then the controls, etc., weren't redrawn, as
> was the case If I returned TRUE.
>
> Q: Is there a better way to do this, and/or what might I be doing
> wrong that's causing the flicker. How do YOU redraw your modal dialogs
> after a screensaver erases everything? Any hints would be most graciously
> welcomed.
What you need to do is detect and respond to update events. There are two
ways to do this, on better than the other. One way is to put in a dialog
event filter which will redraw your stuff when it gets an update event.
The better way is to use user items for all your "special" items; then the
dialog manager will take care of calling your function to draw the items
when they need it.
Tim Dierks
MacDTS, but I speak for my knees
+++++++++++++++++++++++++++
From: bm125@eng.cam.ac.uk (B. Maxwell)
Date: 9 Jun 92 09:55:19 GMT
Organization: Cambridge University Engineering Department, England
In article <1992Jun8.185044.29228@adobe.com> jryan@adobe.com (Jim Ryan) writes:
>I'm drawing a few picts, textEdit fields, and scrollbars in a modal dialog...
>the problem is that when a screensaver kicks in and then out, the picts
>and the TE aren't redrawn.
...
>
>Q: Is there a better way to do this, and/or what might I be doing
>wrong that's causing the flicker. How do YOU redraw your modal dialogs
>after a screensaver erases everything? Any hints would be most graciously
>welcomed.
>
>Thanks a bunch,
>jr
You should use the following procedure to redraw non-standard items in
a dialog box.
1) declare a userItem in your dialog item list that has a rectangle the size
of your pict, or TEfield, or Scrollbars, etc.. (you can also set the rectangle
dynamically using SetDItem(...)
2) setup a structure that contains all of your necessary handles and put a
pointer to it in the reference constant of the dialog window so that you can
get the handles to your picts, scrollbars, and textedit field.
3) write the following routine that does nothing but draw a picture, or update a TE field,
or update a control. etc.
pascal void myDrawDlogItems(dptr,item)
DialogPtr dptr;
short item;
{
PicHandle thePict;
myStructure *ms;
/*get the reference constant, I think this call is right*/
ms = (myStructure *)GetWRefCon(dptr);
/*might want to set the port just to make sure*/
SetPort(dptr);
switch(item) {
case PictItem:
DrawPicture(ms->myPict,&((**(ms->myPict)).picFrame));
break;
case TEItem:
TEUpdate(&thePort->portRect,ms->myTEField);
break;
... and so on
}
return;
}
Now, before calling ModalDialog the first time, just install this routine for
each of the items using SetDItem as in the following calls.
GetDItem(dptr,ItemID,&itemType,&itemHandle,&itemRect);
SetDItem(dptr,ItemId,itemType,(ProcPtr)myDrawDlogItems,&itemRect);
Because your item is a userItem type, whenever there is an update event, ModalDialog
will now call your update routine to draw each of the items. You don't have to worry
about update events in your filter routine anymore.
You may need to mess around with the order of your userItems in the dialog item list
depending upon if the rectangles overlap and if you want events from the items underneath.
Otherwise, this is a clean way to do a messy job.
Have fun,
- --Bruce
---------------------------
From: edw@caligula.cts.com (Ed Watkeys)
Subject: Getting User's Color Control Panel Settings
Date: Mon, 8 Jun 92 13:00:40 EDT
Organization: Distant Software
I'm writing a program where where I'd like to use the colors that the user
has selected in the Color Control Panel. In addition to the highlight color,
I'd like to use the window colors in the content area of my document window.
If I had it my way, I'd use the standard colors, which look the nicest, however
you might come across a user who likes ugly colors :)
Ed
- --
Edwin H. Watkeys III System Administrator
edw@caligula.cts.com Distant Software
AOL: EdWatkeys
+++++++++++++++++++++++++++
From: nerm@apple.com (Dean Yu)
Date: 9 Jun 92 00:19:19 GMT
Organization: Apple Computer, Inc.
In article <01050133.5i2jnp@caligula.cts.com>, edw@caligula.cts.com (Ed Watkeys) writes:
>
> I'm writing a program where where I'd like to use the colors that the user
> has selected in the Color Control Panel. In addition to the highlight color,
> I'd like to use the window colors in the content area of my document window.
> If I had it my way, I'd use the standard colors, which look the nicest, however
> you might come across a user who likes ugly colors :)
>
> Ed
>
Color saves its changes into the default 'wctb' and 'cctb' resources
in the system file. You can use the call GetAuxWin() to get the colors
that are used for the different parts of the windows and scroll bars.
-- Dean Yu
Blue Meanie, Negative Ethnic Role Model, etc.
Apple Computer, Inc.
blah blah blah blah...
---------------------------
From: mgraf@sydvm1.VNET.IBM.COM (Michael Graf)
Date: Tue, 9 Jun 92 12:10:38 EST
Subject: Icons dragging
Organization: Australian Programming Centre (IBMA)
As a novice (but learning) MAC Toolbox programmer, I would like to
provide a nivce interface on an application that I am developing. What I
would like to provide is the means for a user to 'drag' an icon across a
screen and leave it in the new position. Obviously, determining MOUSE DOWNs
in the icon is easy, but I am wondering what the best methodology to use is.
Can anyone 'point' me in the correct direction; what toolbox calls should
I be using ? Are there any snippets or source code around that does this
sort of thing ?
Ideally, later one I would love to be able to do the drag and leave the
background (currently only a white window) the same. Is the same method the
best or is there a better alternative.
Things to note:
- I currently simply use colour ICONS (CICN in fact), but could use PICTs
if it is better. I used icons as I only needed fixed sized pictures.
- I have NO idea how to perform graphic manipulations, as such, so this
is a learning exercise for me in MOST (ALL) ways. Please be as explicit
as possible.
- I use THINK Pascal, but can read C code as well. The actual calls I
should be looking at are the major thing I need, though source code is
of course most welcome.
- Any hints to sections of Inside Mac that I should refer to are also
welcome.
- I would like to use colour for the 'dragged' items, and later on for the
background of the window they are dragged in
- Lastly, this is NOT a Finder program, but should support similar drag
and drop aspects.
Any help or advice would be most appreciated.
Thanx, in advance, for the pointers....
**********************************************************************
Regards,
Michael Graf (mgraf@sydvm1.vnet.ibm.com)
**********************************************************************
+++++++++++++++++++++++++++
From: zobkiw@world.std.com (Joe Zobkiw)
Date: 9 Jun 92 12:34:02 GMT
Organization: The World Public Access UNIX, Brookline, MA
To drag an icons outline (like the Finder) you can simply use Xor drawing
mode, that is, put yourself in Xor, draw the frame of the rectangle, draw
it again (this will make the first one disappear), move it x pixels in the
direction you are going and repeat (draw twice, move, draw twice, move, etc)
Note that you can get fancy if you want to and draw more than just the icons
rectangle (ie: look at the Finder, it outlines the icon _and_ the text of the
icon).
You can also use an offscreen bitmap/pixmap to make the dragging very smooth.
It depends on what you need. This approach will work whether or not you use
an offscreen.
Hope this helps.
- --
- -- joe zobkiw Internet: zobkiw@world.std.com
- -- AOL: AFL Zobkiw
- -- mac.synthesis.MIDI.THINK C.OOP.asm CI$: 70712,515
- -- communications.networks.cool tunes...
---------------------------
From: de19@umail.umd.edu (Dana S Emery)
Subject: Is This Fond PostScript ?!
Date: 9 Jun 92 06:55:42 GMT
Organization: Personal
In article <14271@ucdavis.ucdavis.edu>, lim@iris.ucdavis.edu (Lloyd Lim) writes:
>
> In article <10s9ocINNdd2@agate.berkeley.edu> ewylie@ocf.berkeley.edu (Elizabeth Wylie) writes:
> >
> >I am trying to determine whether a particular font (given a font name and
> >number) has a PostScript counterpart that will be handled by ATM. I've
> >been told that ATM has some callback routines that would help me out,
> >but I don't know what these routines are.
> >
> Yes, the procedure is named fontAvailableATM. It's not hard but it's
> a bit long to describe here.
Suitcase is able to access some field in the FOND which defines the
PS font name (ie TimesRomBol), so ATM shouldnt be necesary (unless one
also needed to confirm the existance of the related 'LWFN'). I vaguely
remember some doc on this, but cant place it just now.
DSE (de19@umail.umd.edu)
+++++++++++++++++++++++++++
From: orpheus@reed.edu (P. Hawthorne)
Date: 9 Jun 92 18:49:19 GMT
Organization: Reed College, Portland, Oregon
ewylie@ocf.berkeley.edu (Elizabeth Wylie) writes:
. I am trying to determine whether a particular font (given a font name and
. number) has a PostScript counterpart that will be handled by ATM. I've been
. told that ATM has some callback routines that would help me out, but I
. don't know what these routines are.
lim@iris.ucdavis.edu (Lloyd Lim) writes:
. Yes, the procedure is named fontAvailableATM. It's not hard but it's
. a bit long to describe here.
de19@umail.umd.edu (Dana S Emery) writes:
. Suitcase is able to access some field in the FOND which defines the
. PS font name (ie TimesRomBol), so ATM shouldnt be necesary (unless one
. also needed to confirm the existance of the related 'LWFN'). I vaguely
. remember some doc on this, but cant place it just now.
In the good old days before there was any such thing as TrueImage,
ahem, you could tell if a FOND resource was for a PostScript typeface
by whether the style map offset in the FONDRec was greater than zero. I
dunno if this has changed with True Type, frankly. Once you got the
printer font file name that you wanted, you could see if the file was
present with OpenResFile, I believe. OpenResFile would traverse the poor
man's search path and do it's best to find the printer font.
Since the question specifically has to do with whether ATM can deal
with the font, it would probably be best to use the ATM backdoor
interface. The best documentation for this (as well as the most lucid,
descriptive and salient discussion of the FOND resource) is available
from Adobe Developer Technical Support. They have a mail server and a
telephone number, but I cannot seem to find pointers to those at the
moment, but you could call the main desk.
As Lloyd said, ATM provides a routine to answer your question. It's
called fontAvailableATM. Before you use it you have to get the backdoor
interface working. Adobe assumes you are using Think C and they have been
unable to come up with a backdoor interface for other compilers. The
package is available for anonymous ftp on sumex-aim.stanford.edu.
Just in case, here is my code for using ATM with Think Pascal. It worked
fine once, but the caveat is that I haven't used or looked at for quite
some time. The last version of ATM I tested it with was 2.0.3, I think.
I haven't cleaned it up at all, so there may not be disassembly on all of
the inlines, since they were handcompiled with MacsBug before I even got
the Motorola user manuals. The inlines are for use only by the routines
that actually call on the ATM backdoor, so you should not use any of the
whateverJump routines, just whatever.
- ----------- Cut here and you'll have to buy a new monitor
Type
FixedMatrix = Record
a, b, c, d, tx, ty: Fixed;
End;
FixedMatrixPtr = ^FixedMatrix;
ATMProcs3 = Record
Version: Longint;
fontAvailableATMProc: ProcPtr;
showTextATMProc: ProcPtr;
xyshowTextATMProc: ProcPtr;
End;
{initATM initializes the ATM interface, returns 1 if ATM itself is available}
{and the procsets are correctly initialized}
Function initATM: Integer;
Type
ParamBlockRecPtr = ^ParamBlockRec;
Var
a: Ptr;
c: ParamBlockRecPtr;
result: OSErr;
Procedure Fail;
Begin
initATM := 0;
Exit(initATM);
End;
Begin
atmOpen := false;
{Do you have inline for NewClearPtr? If so, you may wanna use it, or ask me.}
{This should work fine though.}
Ptr(c) := NewPtr(SizeOf(ParamBlockRec));
If c = Nil Then
Fail;
c^.ioCompletion := Nil;
atmProcs.version := ATMProcs3Version;
result := OpenDriver('.ATM', c^.ioRefNum);
If (result <> noErr) Then
Fail;
a := @atmProcs;
BlockMove(@a, @c^.csParam, 4);
c^.csCode := ATMProcsStatusCode;
result := PBStatus(@c^, false);
If (result <> noErr) Then
Fail;
a := Ptr(Clean(atmProcs.fontAvailableATMProc) + 2);
BlockMove(a, @atmProcs.fontAvailableATMProc, 4);
a := Ptr(Clean(atmProcs.showTextATMProc) + 2);
BlockMove(a, @atmProcs.showTextATMProc, 4);
a := Ptr(Clean(atmProcs.xyshowTextATMProc) + 2);
BlockMove(a, @atmProcs.xyshowTextATMProc, 4);
atmOpen := true;
initATM := 1;
End;
Function fontAvailableATMJump (style, family: Integer; aProc: ProcPtr):
Integer;
Inline
$205F, $4E90, $3E80;
{fontAvailableATM returns 1 iff ATM can image this family and style}
Function fontAvailableATM (family, style: Integer): Integer;
Begin
If Not atmOpen Then
fontAvailableATM := 0
Else
fontAvailableATM := fontAvailableATMJump(style, family,
atmProcs.fontAvailableATMProc);
End;
Function showTextATMJump (matrix: Univ Ptr; length: Integer; text: Univ Ptr;
aProc: ProcPtr): Integer;
Inline
$205F, {pop into a0}
$4E90, {jsr to a0}
$48C0, {clean d0}
$3F00; {push d0}
{showTextATM shows length characters starting at text transformed by the}
{specified matrix. Returns the number of characters not shown. Matrix maps}
{one point character space to device space, relative to current pen}
{position. Matrix's tx and ty components are updated.}
Function showTextATM (text: Ptr; length: Integer; Var Matrix: FixedMatrix):
Integer;
Begin
If Not atmOpen Then
showTextATM := length
Else
showTextATM := showTextATMJump(@matrix, length, text,
atmProcs.showTextATMProc);
End;
Function xyshowTextATMJump (displacements, matrix: Univ Ptr; length: Integer;
text: Univ Ptr; aProc: ProcPtr): Integer;
Inline
$205F, {pop into a0}
$4E90, {jsr to a0}
$48C0, {clean d0}
$3F00; {push d0}
{Show length characters starting at text transformed by the specified}
{matrix. Matrix maps one point character space to device space, relative to}
{current pen position. Matrix's tx and ty components are updated. Character}
{x and y widths are specified by displacements. Returns the number of}
{characters not shown}
Function xyshowTextATM (text: Ptr; length: Integer; Var Matrix,
Displacements: FixedMatrix): Integer;
Begin
If Not atmOpen Then
xyshowTextATM := length
Else
xyshowTextATM := xyshowTextATMJump(@displacements, @matrix, length, text,
atmProcs.xyshowTextATMProc);
End;
- ------------ Wish I could put the scissors character from Zapf Dingbats here.
Theus
orpheus@reed.edu
---------------------------
From: peter@cujo.curtin.edu.au (Peter N Lewis)
Subject: Warning: THINK Pascal glue for GetZoneList is dangerous!
Organization: Curtin University of Technology
Date: Mon, 8 Jun 1992 09:50:21 GMT
Hi All,
Consider yourselves warned: The THINK Pascal (don't know about MPW)
glue code for GetZoneList and GetLocalZones is dangerous, it blats
the word at location A0+$1C before it sets A0 to point to the
paramblock. This can cause any number of possible errors, therefore
the GetZoneList and GetLocalZones call should be avoided. Fortunately,
all they do is fill in a few fields in the paramblock record and call
PBControl, so you can avoid them easily enough - once you know you
should! This applies for THINK Pascal 4.0.1, I don't know about earlier
versions...
Take (lots of!) care,
Peter.
GETZONELIST
+0010 0002FE LINK A6,#$0000
+0014 000302 SUBQ.W #$2,A7
+0016 000304 PEA -$025C(A5)
+001A 000308 CLR.B -(A7)
+001C 00030A JSR Anon10+$011C ; Call GetZoneList
+0020 00030E MOVE.W (A7)+,-$0102(A5)
+0024 000312 UNLK A6
+0026 000314 JSR Anon1 ; 00000004
+002A 000318 UNLK A6
+002C 00031A RTS
+011C 000280 MOVE.W #$00F6,D0
+0120 000284 MOVE.W #$0006,$001C(A0) <-------------- BAD BAD BAD!
+0126 00028A MOVE.W #$0006,D2
+012A 00028E BRA.S Anon10+$014E ; 000002B2
+++++++++++++++++++++++++++
From: siegel@world.std.com (Rich Siegel)
Date: 8 Jun 92 14:14:14 GMT
Organization: GCC Technologies
In article <1992Jun8.095021.21443@cujo.curtin.edu.au> peter@cujo.curtin.edu.au (Peter N Lewis) writes:
>Hi All,
>
>Consider yourselves warned: The THINK Pascal (don't know about MPW)
>glue code for GetZoneList and GetLocalZones is dangerous, it blats
>the word at location A0+$1C before it sets A0 to point to the
>paramblock. This can cause any number of possible errors, therefore
>the GetZoneList and GetLocalZones call should be avoided. Fortunately,
>all they do is fill in a few fields in the paramblock record and call
>PBControl, so you can avoid them easily enough - once you know you
>should! This applies for THINK Pascal 4.0.1, I don't know about earlier
>versions...
>
>Take (lots of!) care,
> Peter.
>
>GETZONELIST
>+0010 0002FE LINK A6,#$0000
>+0014 000302 SUBQ.W #$2,A7
Just out of curiosity, where did you get this 'glue' for GetZoneList;
and what library did you add to your project? There are a couple of strange
things here: first, the disassembly you gave is nothing at all like the
disassembly that DumpObj gives for the ZoneList module from THINK Pascal's
nAppleTalk.Lib; second, there are only a few MacsBug symbols in the interface
glue libraries, and "GETZONELIST" isn't one of them, so why does your
disassembly have one?; third, what sort of program is executing here, that
the disassembly address is not in the system heap and not in the application
heap, but somewhere very low in memory?
The DumpObj output for GetZoneList from MPW's own Interface.o and
THINK Pascal 4.0's "nAppleTalk.Lib" are virtually identical, and neither
one bears any resemblance to the disassembly you've posted.
I think it would be wise to refrain from posting any alarms until
this is completely figured out; it's not as cut-and-dried as you seem to
think.
R.
- --
- -----------------------------------------------------------------------
Rich Siegel Internet: siegel@world.std.com
Software Engineer & Toolsmith
GCC Technologies
+++++++++++++++++++++++++++
From: REEKES@applelink.apple.com (Jim Reekes)
Date: 9 Jun 92 07:46:28 GMT
Organization: Apple Computer, Inc.
In article <1992Jun8.095021.21443@cujo.curtin.edu.au>, peter@cujo.curtin.edu.au (Peter N Lewis) writes:
>
> Hi All,
>
> Consider yourselves warned: The THINK Pascal (don't know about MPW)
> glue code for GetZoneList and GetLocalZones is dangerous, it blats
> the word at location A0+$1C before it sets A0 to point to the
> paramblock. This can cause any number of possible errors, therefore
> the GetZoneList and GetLocalZones call should be avoided. Fortunately,
> all they do is fill in a few fields in the paramblock record and call
> PBControl, so you can avoid them easily enough - once you know you
> should! This applies for THINK Pascal 4.0.1, I don't know about earlier
> versions...
>
> Take (lots of!) care,
> Peter.
>
> GETZONELIST
> +0010 0002FE LINK A6,#$0000
> +0014 000302 SUBQ.W #$2,A7
> +0016 000304 PEA -$025C(A5)
> +001A 000308 CLR.B -(A7)
> +001C 00030A JSR Anon10+$011C ; Call GetZoneList
> +0020 00030E MOVE.W (A7)+,-$0102(A5)
> +0024 000312 UNLK A6
> +0026 000314 JSR Anon1 ; 00000004
> +002A 000318 UNLK A6
> +002C 00031A RTS
>
> +011C 000280 MOVE.W #$00F6,D0
> +0120 000284 MOVE.W #$0006,$001C(A0) <-------------- BAD BAD BAD!
> +0126 00028A MOVE.W #$0006,D2
> +012A 00028E BRA.S Anon10+$014E ; 000002B2
This is the current MPW 3.2 glue. It does the right thing.
0000013C: 303C 00F6 MOVE.W #$00F6,D0
00000140: 343C 0006 MOVE.W #$0006,D2
00000144: 6022 BRA.S *+$0024 ; 00000168
00000168: 225F MOVEA.L (A7)+,A1
0000016A: 121F MOVE.B (A7)+,D1
0000016C: 205F MOVEA.L (A7)+,A0
0000016E: 3142 001C MOVE.W D2,$001C(A0)
00000172: 317C FFD7 0018 MOVE.W #$FFD7,$0018(A0)
00000178: 3140 001A MOVE.W D0,$001A(A0)
0000017C: 4A01 TST.B D1
0000017E: 6604 BNE.S *+$0006 ; 00000184
00000180: A004 _Control ; A004
00000182: 6002 BRA.S *+$0004 ; 00000186
00000184: A404 _Control ,Sys ; A404
00000186: 3E80 MOVE.W D0,(A7)
00000188: 4ED1 JMP (A1)
- -----------------------------------------------------------------------
Jim Reekes, Polterzeitgeist | Macintosh Toolbox Engineering
| Sound Manager Expert
Apple Computer, Inc. | "All opinions expressed are mine, and do
20525 Mariani Ave. MS: 81-KS | not necessarily represent those of my
Cupertino, CA 95014 | employer, Apple Computer Inc."
+++++++++++++++++++++++++++
From: peter@cujo.curtin.edu.au (Peter N Lewis)
Date: 10 Jun 92 03:31:41 GMT
Organization: NCRPDA, Curtin University
In article <BpJ67r.CCB@world.std.com>, siegel@world.std.com (Rich Siegel) writes:
>
> In article <1992Jun8.095021.21443@cujo.curtin.edu.au> peter@cujo.curtin.edu.au (Peter N Lewis) writes:
> >Consider yourselves warned: The THINK Pascal (don't know about MPW)
> >glue code for GetZoneList and GetLocalZones is dangerous, it blats
> >the word at location A0+$1C before it sets A0 to point to the
> >paramblock. This can cause any number of possible errors, therefore
> >the GetZoneList and GetLocalZones call should be avoided. Fortunately,
> >all they do is fill in a few fields in the paramblock record and call
> >PBControl, so you can avoid them easily enough - once you know you
> >should! This applies for THINK Pascal 4.0.1, I don't know about earlier
> >versions...
> Just out of curiosity, where did you get this 'glue' for GetZoneList;
> and what library did you add to your project? There are a couple of strange
> things here: first, the disassembly you gave is nothing at all like the
> disassembly that DumpObj gives for the ZoneList module from THINK Pascal's
> nAppleTalk.Lib; second, there are only a few MacsBug symbols in the interface
> glue libraries, and "GETZONELIST" isn't one of them, so why does your
> disassembly have one?; third, what sort of program is executing here, that
> the disassembly address is not in the system heap and not in the application
> heap, but somewhere very low in memory?
I wish you had brought this up with me in Email, but since you want it in
public, thats fine, it means more people will find out about, and avoid, this
problem. The glue code for GetZoneList comes from the nAppleTalk.lib file,
straight off my original THINK Pascal 4.00 disks. The disassembly is
nothing like what DumpObj gives simply because it was disassembled using
ResEdit's code disassembler - I can understand how many people would be
unaware that its possible to get the text of the disassembly out of ResEdit,
since it involves selecting the hexdump on the right, choosing copy to
get the disassembly. Obviously the numbers are small since they are
offsets into procedures (anonymous ones in the library). The GETZONELIST
is the name of the program, and thus the symbol appears before the start
of the main line code.
> The DumpObj output for GetZoneList from MPW's own Interface.o and
> THINK Pascal 4.0's "nAppleTalk.Lib" are virtually identical, and neither
> one bears any resemblance to the disassembly you've posted.
Yes, you are quite right - they are "virtually" identical. And if you look
at the glue code for GETZONELIST you will notice that one of the bits that
is not identical is the fact that the THINK Pascal GetZoneList and
GetLocalZones glue code blatts a word in memory addressed as $1C(A0)
and THEN sets up A0, whereas the MPW glue does not blatt this word
until after it has set A0 to point to the paramblock...
> I think it would be wise to refrain from posting any alarms until
> this is completely figured out; it's not as cut-and-dried as you seem to
> think.
Curious - I thought it was wise after discovering a potentially dangerous
bug and thoroughly verifying its existance to warn people of the problem.
I also think it would be wise to check whether such a warning is in fact
correct before posting suggesting that it is not.
If you are not interested in the details of this bug, read no further.
For your reading pleasure I will now give the full and gorry details
of the bug, from Project file to assembly code error:
The project file consists of:
Runtime.Lib - straight off the original TP4.00 disk
Interfaces.Lib - straight off the original TP4.00 disk
nAppleTalk.Lib - straight off the original TP4.00 disk
AppleTalk.p - The AppleTalk interface file
GetZoneList.p - My test code.
GetZoneList.p is:
program GetZoneList;
uses
AppleTalk;
var
pb: XPPParamBlock;
oe: OSErr;
begin
oe := GetZoneList(@pb, false);
end.
NOTE: Don't ever run the above program, it is simple a call to GetZoneList
so that I can look at the compiled code resource and check what is happening.
Obviously to use GetZoneList in practice you would need to set up many
fields of the record.
And now a disassembly of CODE resource id 1, got from the ResEdit code
editor. I have removed the hexdump info normally on the right of the
listing, since it doesn't fit in 80 columns, and have removed the
initialization procedures, so that only the main line and the XPP glue
procedure are left. If you want the rest, you can compile the above
program or mail me...
This procedure contains the glue code for XPP calls:
Anon10
+0000 000164 MOVE.W #$0017,D0
+0004 000168 BRA Anon10+$0176 ; 000002DA
+0008 00016C MOVE.W #$0018,D0
+000C 000170 BRA Anon10+$0176 ; 000002DA
+0010 000174 MOVE.W #$0019,D0
+0014 000178 BRA Anon10+$0176 ; 000002DA
+0018 00017C MOVE.W #$00F5,D0
+001C 000180 BRA Anon10+$00CA ; 0000022E
+0020 000184 MOVE.W #$00F4,D0
+0024 000188 BRA Anon10+$00CA ; 0000022E
+0028 00018C MOVE.W #$00F3,D0
+002C 000190 BRA Anon10+$00CA ; 0000022E
+0030 000194 MOVE.W #$00F8,D0
+0034 000198 BRA Anon10+$00CA ; 0000022E
+0038 00019C MOVE.W #$00F7,D0
+003C 0001A0 BRA Anon10+$00CA ; 0000022E
+0040 0001A4 MOVE.W #$00F6,D0
+0044 0001A8 BRA Anon10+$00CA ; 0000022E
+0048 0001AC MOVE.W #$00FD,D0
+004C 0001B0 BRA.S Anon10+$00CA ; 0000022E
+004E 0001B2 MOVE.W #$00FB,D0
+0052 0001B6 BRA.S Anon10+$00CA ; 0000022E
+0054 0001B8 MOVE.W #$00FA,D0
+0058 0001BC BRA.S Anon10+$00CA ; 0000022E
+005A 0001BE MOVE.W #$00FC,D0
+005E 0001C2 BRA.S Anon10+$00CA ; 0000022E
+0060 0001C4 MOVE.W #$0100,D0
+0064 0001C8 BRA.S Anon10+$00CA ; 0000022E
+0066 0001CA MOVE.W #$00FE,D0
+006A 0001CE BRA.S Anon10+$00CA ; 0000022E
+006C 0001D0 MOVE.W #$0102,D0
+0070 0001D4 BRA.S Anon10+$00CA ; 0000022E
+0072 0001D6 MOVE.W #$0103,D0
+0076 0001DA BRA.S Anon10+$00CA ; 0000022E
+0078 0001DC MOVE.W #$00FE,D0
+007C 0001E0 BRA.S Anon10+$00BE ; 00000222
+007E 0001E2 MOVE.W #$00FA,D0
+0082 0001E6 BRA.S Anon10+$00BE ; 00000222
+0084 0001E8 MOVE.W #$00FF,D0
+0088 0001EC BRA.S Anon10+$00BE ; 00000222
+008A 0001EE MOVE.W #$00FD,D0
+008E 0001F2 BRA.S Anon10+$00BE ; 00000222
+0090 0001F4 MOVE.W #$00FC,D0
+0094 0001F8 BRA.S Anon10+$00BE ; 00000222
+0096 0001FA MOVE.W #$00FB,D0
+009A 0001FE BRA.S Anon10+$00BE ; 00000222
+009C 000200 MOVE.W #$0100,D0
+00A0 000204 BRA.S Anon10+$00BE ; 00000222
+00A2 000206 MOVE.W #$00F9,D0
+00A6 00020A BRA.S Anon10+$00BE ; 00000222
+00A8 00020C MOVE.W #$00F8,D0
+00AC 000210 BRA.S Anon10+$00BE ; 00000222
+00AE 000212 MOVE.W #$0102,D0
+00B2 000216 BRA.S Anon10+$00BE ; 00000222
+00B4 000218 MOVE.W #$0101,D0
+00B8 00021C BRA.S Anon10+$00BE ; 00000222
+00BA 00021E MOVE.W #$0103,D0
+00BE 000222 MOVEA.L $0006(A7),A0
+00C2 000226 MOVE.W #$FFF5,$0018(A0)
+00C8 00022C BRA.S Anon10+$0136 ; 0000029A
+00CA 00022E MOVEA.L $0006(A7),A0
+00CE 000232 MOVE.W #$FFF6,$0018(A0)
+00D4 000238 BRA.S Anon10+$0136 ; 0000029A
+00D6 00023A MOVE.W #$00FF,D0
+00DA 00023E BRA.S Anon10+$0136 ; 0000029A
+00DC 000240 MOVE.W #$00FE,D0
+00E0 000244 BRA.S Anon10+$0136 ; 0000029A
+00E2 000246 MOVE.W #$00F8,D0
+00E6 00024A BRA.S Anon10+$0136 ; 0000029A
+00E8 00024C MOVE.W #$00F9,D0
+00EC 000250 BRA.S Anon10+$0136 ; 0000029A
+00EE 000252 MOVE.W #$00F7,D0
+00F2 000256 BRA.S Anon10+$0136 ; 0000029A
+00F4 000258 MOVE.W #$00FC,D0
+00F8 00025C BRA.S Anon10+$0136 ; 0000029A
+00FA 00025E MOVE.W #$00FD,D0
+00FE 000262 BRA.S Anon10+$0136 ; 0000029A
+0100 000264 MOVE.W #$00FB,D0
+0104 000268 BRA.S Anon10+$0136 ; 0000029A
+0106 00026A MOVE.W #$00FA,D0
+010A 00026E BRA.S Anon10+$0136 ; 0000029A
Here is the entry point for the GetLocalZones glue code
+010C 000270 MOVE.W #$00F6,D0
+0110 000274 MOVE.W #$0005,$001C(A0) <--- Note no set up of A0
+0116 00027A MOVE.W #$0005,D2
+011A 00027E BRA.S Anon10+$014E ; 000002B2
Here is the entry point for the GetZoneList glue code
+011C 000280 MOVE.W #$00F6,D0
+0120 000284 MOVE.W #$0006,$001C(A0) <--- Note no set up of A0
+0126 00028A MOVE.W #$0006,D2
+012A 00028E BRA.S Anon10+$014E ; 000002B2
+012C 000290 MOVE.W #$00F6,D0
+0130 000294 MOVE.W #$0007,D2
+0134 000298 BRA.S Anon10+$014E ; 000002B2
+0136 00029A MOVEA.L (A7)+,A1
+0138 00029C MOVE.B (A7)+,D1
+013A 00029E MOVEA.L (A7)+,A0
+013C 0002A0 MOVE.W D0,$001A(A0)
+0140 0002A4 TST.B D1
+0142 0002A6 BNE.S Anon10+$0148 ; 000002AC
+0144 0002A8 _Control ; A004
+0146 0002AA BRA.S Anon10+$014A ; 000002AE
+0148 0002AC _Control ,Sys ; A404
+014A 0002AE MOVE.W D0,(A7)
+014C 0002B0 JMP (A1)
GetZoneList and GetLocalZones set up D0 and D2, blatt a word and then
continue here with a PBControl call:
+014E 0002B2 MOVEA.L (A7)+,A1
+0150 0002B4 MOVE.B (A7)+,D1
Ahh, finally we load A0 with the address of the param block - a bit late now.
+0152 0002B6 MOVEA.L (A7)+,A0
The next line correctly sets the word, AFTER loading A0. The previous
assignement to $1C(A0) in the glue code is in error and should be removed.
+0154 0002B8 MOVE.W D2,$001C(A0)
+0158 0002BC MOVE.W #$FFD7,$0018(A0)
+015E 0002C2 MOVE.W D0,$001A(A0)
+0162 0002C6 TST.B D1
+0164 0002C8 BNE.S Anon10+$016A ; 000002CE
+0166 0002CA _Control ; A004
+0168 0002CC BRA.S Anon10+$016C ; 000002D0
+016A 0002CE _Control ,Sys ; A404
+016C 0002D0 MOVE.W D0,(A7)
+016E 0002D2 JMP (A1)
+0170 0002D4 SUBI.B #$5850,$5000(A6) ; 'P'
+0176 0002DA MOVEA.L $0004(A7),A0
+017A 0002DE MOVEA.L AtalkHk2,A1
+017E 0002E2 MOVE.L (A7)+,(A7)
+0180 0002E4 JSR $0002(A1)
+0184 0002E8 MOVEA.L (A7)+,A0
+0186 0002EA MOVE.W D0,-(A7)
+0188 0002EC JMP (A0)
And this is the main line code:
GETZONELIST
+0000 0002EE JSR Anon1+$0016 ; 0000001A
+0004 0002F2 JSR Anon7 ; 00000138
+0008 0002F6 JSR Anon4 ; 000000E2
+000C 0002FA JSR Anon5+$000A ; 000000F8
+0010 0002FE LINK A6,#$0000
+0014 000302 SUBQ.W #$2,A7
+0016 000304 PEA -$025C(A5)
+001A 000308 CLR.B -(A7)
+001C 00030A JSR Anon10+$011C <--- Here is the call to GetZoneList
Note that no set up of A0 is done at this end either. Tracing back we
find that the last assignment of A0 is in Anon5, either to the stack
pointer A7, or set by SetApplLimit, MacApplZone, or MoreMasters (if any of
those traps modify A0).
+0020 00030E MOVE.W (A7)+,-$0102(A5)
+0024 000312 UNLK A6
+0026 000314 JSR Anon1 ; 00000004
+002A 000318 UNLK A6
+002C 00031A RTS
+002E 00031C DC.B $80+$0B, 'GETZONELIST'
+003A 000328 DC.W $0000 ; size of literals
I have verified that the MPW glue does not contain this error. And I am
100% confident that the nAppleTalk.Lib glue as supplied on my original
4.00 INTERNATIONAL original disk contains this error, and therefore
writes to a random word in memory (worse a word just off A0, which will
likely be pointing at something important). Since this can easily cause
a crash (it would address error if A0 happened to be odd), or can cause
all sorts of subtle behaviour. I have no qualms about posting this, and
I hope it doesn't bite anyone else.
Take (as I said before, lots of!) care,
Peter.
______________________________________________________________________
Peter N Lewis, NCRPDA, Curtin University peter@cujo.curtin.edu.au
GPO Box U1987, Perth WA 6001, AUSTRALIA FAX: +61 9 367 8141
+++++++++++++++++++++++++++
From: keith@taligent.com (Keith Rollin)
Date: 10 Jun 92 21:11:19 GMT
Organization: Taligent
In article <1992Jun10.033141.6872@cujo.curtin.edu.au>, peter@cujo.curtin.edu.au
(Peter N Lewis) writes:
>
> > In article <1992Jun8.095021.21443@cujo.curtin.edu.au>
peter@cujo.curtin.edu.au (Peter N Lewis) writes:
>
> > >Consider yourselves warned: The THINK Pascal (don't know about MPW)
> > >glue code for GetZoneList and GetLocalZones is dangerous, it blats
> > >the word at location A0+$1C before it sets A0 to point to the
> > >paramblock.
>
> I have verified that the MPW glue does not contain this error.
>
I think that the problem is limited to THINK Pascal (as long as Rich or someone
else with THINK Pascal can verify the problem). A number of people have verified
that it does _not_ exist in MPW, and I just checked THINK C 5.0.2 and it seems
OK, too.
- --
Keith Rollin
Phantom Programmer
Taligent, Inc.
---------------------------
End of C.S.M.P. Digest
**********************